package cn.gson.financial.kernel.service.impl;

import cn.gson.financial.kernel.service.OssService;
import cn.gson.financial.kernel.utils.IdCreateUtil;
import cn.gson.financial.kernel.utils.TimeUtil;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;

/**
 * @Author：ywh
 * @Date：2023/4/11 11:10
 * @Description：
 */
@Service
@Slf4j
public class OssServiceImpl implements OssService{
    @Value("${oss.endpoint}")
    private String endpoint;
    @Value("${oss.accessKeyId}")
    private String accessKeyId;
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;
    @Value("${oss.bucketName}")
    private String bucketName;
    @Value("${oss.bucketPath.prefix}")
    private String ossPrefix;

    public String uploadFile(MultipartFile multipartFile){
        //获取文件的后缀名;带小数点 eg：xxx.pdf,输出就是.pdf
        String fileType = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
        //docId，也就是上传到oss上的目录
        String param = TimeUtil.getYearMonthDay() +"/"+ IdCreateUtil.createFileId() + "_" +IdCreateUtil.createTaskId() + fileType;
        String fileId =  "organize" +param;
        String ossAbsolutePath = ossPrefix + param;
        System.out.println(ossAbsolutePath);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossAbsolutePath, multipartFile.getInputStream());
            // 设置该属性可以返回response。如果不设置，则返回的response为空。
            putObjectRequest.setProcess("true");
            // 上传文件。如果上传成功，则返回200。result.getResponse().getStatusCode()
            ossClient.putObject(putObjectRequest);
            return fileId;
        } catch (OSSException oe) {
            log.info("捕获到OSSException，这意味着您的请求已发送到OSS，但由于某种原因被错误响应拒绝。");
        } catch (ClientException ce) {
            log.info("没有ClientException，这意味着客户端在尝试与OSS通信时遇到了严重的内部问题，例如无法访问网络");
        } catch (SocketException e){
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    @Override
    public byte[] downLoadFile(String fileId){
        fileId = fileId.substring(8);//将前缀去掉
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        String ossAbsolutePath = ossPrefix + fileId;
        System.out.println(ossAbsolutePath);
        try {
//            ossClient.getObject(new GetObjectRequest(bucketName, ossAbsolutePath), new File(localFilePath));
            //ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
            OSSObject ossObject = ossClient.getObject(bucketName, ossAbsolutePath);
            InputStream inputStream = ossObject.getObjectContent();
            return IOUtils.toByteArray(inputStream);
        } catch (OSSException oe) {
            log.info("捕获到OSSException，这意味着您的请求已发送到OSS，但由于某种原因被错误响应拒绝。");
            oe.printStackTrace();
        } catch (SocketException e){
            e.printStackTrace();
        }catch (Throwable ce) {
            log.info("没有ClientException，这意味着客户端在尝试与OSS通信时遇到了严重的内部问题，例如无法访问网络");
            ce.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return null;
    }

    @Override
    @Async
    public Boolean deleteFile(String fileId) {
        fileId = fileId.substring(8);//将前缀去掉
        String ossAbsolutePath = ossPrefix + fileId;
        System.out.println(ossAbsolutePath);
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(bucketName, ossAbsolutePath);
            return true;
        } catch (OSSException oe) {
            log.info("捕获到OSSException，这意味着您的请求已发送到OSS，但由于某种原因被错误响应拒绝。");
            oe.printStackTrace();
        } catch (Throwable ce) {
            log.info("没有ClientException，这意味着客户端在尝试与OSS通信时遇到了严重的内部问题，例如无法访问网络");
            ce.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return false;
    }
}

